/**
 *
 */
package name.yzhu.database;

import java.net.URL;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Cache;
import org.hibernate.InvalidMappingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.util.ConfigHelper;

/**
 * @author yhzhu
 *
 */
public class DbSupport {
	private  SessionFactory sf = null;
	private  Configuration conf = null;
	private  URL DEFAULT_CONFIG_FILE = ConfigHelper.locateConfig("hbn.cfg.xml");
	private  final Log LOG = LogFactory.getLog(DbSupport.class);
	private  final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
	private  final ThreadLocal<IDbUtil> threadDbutil=new ThreadLocal<IDbUtil>();

	public DbSupport(URL  hibernateCfgFile,Properties properties) {
		if(sf == null)
		{
			if (hibernateCfgFile == null) {
				hibernateCfgFile = DEFAULT_CONFIG_FILE;
			}
			LOG.info("Load conf file : " + hibernateCfgFile.toString());
			conf = new Configuration().configure(hibernateCfgFile);
			setProperties(properties);
		}
	}

	public DbSupport() {
		LOG.info("Load default conf file : " + DEFAULT_CONFIG_FILE.toString());
		conf = new Configuration().configure(DEFAULT_CONFIG_FILE);
	}

	public void addResource(String classHbmxml){
		conf.addResource(classHbmxml);

	}

	public void addUrl(URL url){
		try{
		conf.addURL(url);
		}catch(InvalidMappingException e){
			LOG.warn("Add URL error:"+url.toString());
			throw e;
		}
	}

	public void addClass(Class<?> persistentClass){
		conf.addClass(persistentClass);
	}

	public void setProperties(Properties properties){
		if(properties!=null){
			conf.addProperties(properties);
		}
	}

	public void buildSessionFactory(){
		sf = conf.buildSessionFactory();
		LOG.info("SessionFactory build.");
	}

	public  IDbUtil getDbUtil()
	{
		IDbUtil util=threadDbutil.get();
		if(util==null){
			util=new DbUtil(this);
			threadDbutil.set(util);
		}
		return util;
	}

	public void closeUtil() {
		closeSession();
		threadDbutil.set(null);
	}

	public synchronized Session getSession()
	{
		Session session = threadSession.get();
		if(session == null || !session.isOpen())
		{
			session = sf.openSession();
			threadSession.set(session);
		}
		return session;
	}

	public synchronized Session getStandaloneSession()
	{
		return sf.openSession();
	}

	public synchronized void closeSession()
	{
		Session session = threadSession.get();
		if(session != null && session.isOpen())
		{
			session.close();
		}
		threadSession.set(null);
	}

	public void close(){
		sf.close();
	}

	public String properties2String() {
		StringBuilder sb = new StringBuilder();
		for(Entry<Object, Object> s : conf.getProperties().entrySet()) {
			sb.append(s.getKey());
			sb.append(" = ");
			sb.append(String.valueOf(s.getValue()));
			sb.append("\n");
		}
		return sb.toString();
	}

	public Cache getCach(){
		return sf.getCache();
	}

}